// 1.rest剩余参数
// function fn(...args){}
// fn(1,2,3)
// 这样再函数里面打印的args 就是 一个数组 [1,2,3]
// 2.扩展运算符， rest剩余参数的逆运算
// ...[14, 3, 77]  就是   14,3,77
// 3. Array.prototype.slice.call(arguments)；arguments对象不是数组，而是一个类似数组的对象，使用slice将其转为数组, arr.slice()  实现浅拷贝，一层
// 4. Array.form() 将可迭代对象转化为数组， iterator遍历器
// new Array(2)  Array.of()
//
// let ab = { ...a, ...b };
// 等同于
// let ab = Object.assign({}, a, b);

//   数组去重  [...new Set(arr)]; has
let setData1 = [1, 2, 3, 4],
  setData2 = [2, 3, 4, 9, 19, 91];

function diffrenceBy(...args) {
  return args.reduce((prev, curr, index) => {
    return prev.filter((item) => {
      return curr.includes(item);
    });
  });
}
console.log(diffrenceBy(setData1, setData2));

// 2.  对象数组去重 diffrenceBy uniqBy
var arr3 = [
  { id: 1, name: "zs" },
  { id: 2, name: "ls" },
  { id: 2, name: "zs" },
  { id: 2, name: "ww" },
  { id: 1, name: "zs" },
];
console.log(_.uniqBy(arr3, "id"));

function myUniqBy(arr, prop) {
  let obj = {};
  return arr.reduce((prev, curr) => {
    // 将需要比对的key的value值 当做对象obj的属性
    // 利用了对象的key不能重复的规则
    obj[curr[prop]] ? null : (obj[curr[prop]] = true && prev.push(curr));
    return prev;
  }, []);
}
console.log(myUniqBy(arr3, "name"));

// 3.1 实现对象的map方法
// 3.1.1. reduce方法 实现对象的map方法
Object.prototype.objMap = function (handleFn, thisVal) {
  return Object.keys(this).reduce((prev, curr, index, arr) => {
    console.log(111, thisVal, curr, this[curr], this);
    prev[curr] = handleFn.call(thisVal, curr, this[curr], this);
    return prev;
  }, {});
};
console.log(obj.objMap((item) => item + "---", { name: "李四" }));

// 3.1.2. for in 循环的方式
var obj = { name: "zs", age: 24, addr: "北京" };
Object.prototype.objMap = function (handleFn, thisValue) {
  let res = {};
  for (var key in this) {
    res[key] = handleFn.call(thisValue, this[key], key, this);
  }
  return res;
};

// 3.2 实现map方法
Array.prototype._map = function (cb) {
  if (typeof cb !== "function") {
    return new Error("参数错误，请传入一个回调函数作为参数！");
  }
  return this.reduce((previousVal, currentVal, item, arr) => {
    previousVal.push(cb(currentVal, item, arr));
    return previousVal;
  }, []);
};

var arr = [1, 2, 3, 4, 5];
console.log(arr._map((item) => item * 2));

// 4. 实现filter方法
Array.prototype._filter = function (cb, thisValue = {}) {
  if (typeof cb !== "function") {
    throw new Error("当前参数传递错误，请重试");
  }

  return this.reduce((previousVal, currentVal, index, arr) => {
    console.log(111, thisValue);
    cb.call(thisValue, currentVal, index, arr)
      ? previousVal.push(currentVal)
      : null;
    return previousVal;
  }, []);
};

var arr = [1, 2, 3, 4, 5];
console.log(arr._filter((item) => item % 2 === 0, { name: "zs" }));

// 5. 实现一个reduce方法
Array.prototype.myReduce = function (cb, initValue) {
  var initTmp = initValue === undefined ? this[0] : initValue;
  var i = initValue === undefined ? 1 : 0;

  for (i; i < this.legnth; i++) {
    initTmp = cb(initTmp, this[i], i, this);
  }

  return initTmp;
};

const abc = arr.myReduce((prev, curr, index, arrTmp) => {
  console.log(prev, curr, index, arrTmp);
  return (prev += curr);
});
